#include "TCPServer.h"
#include "TCPClient.h"
#include "../ZPL.h"
#include <pthread.h>
#include <list>

CTCPServer::CTCPServer() : CNetwork()
{
    m_nPort = 5060;
}

CTCPServer::~CTCPServer()
{

}

bool CTCPServer::Init()
{
    m_socketServer = socket(AF_INET, SOCK_STREAM, 0);
    if(m_socketServer < 0)
    {
        return false;
    }
    printf("TCP Server create socket success\n");

    struct sockaddr_in local;
    local.sin_family = AF_INET;
    local.sin_port = htons(m_nPort);
    local.sin_addr.s_addr = INADDR_ANY;
    bzero(local.sin_zero, sizeof(local.sin_zero));

    int ret = bind(m_socketServer, (struct sockaddr*)&local, sizeof(struct sockaddr));
    if(ret < 0)
    {
        close(m_socketServer);
        return false;
    }
    printf("TCP Server listen bind success\n");

    ret = listen(m_socketServer, 5);
    if(ret < 0)
    {
        close(m_socketServer);
        return false;
    }
    printf("TCP Server listen socket success\n");

    return true;
}

ssize_t GetPackage(int sock, std::list<char>& vPackage)
{
    ssize_t sPackage = 0;
    char szBuffer[2] = { 0x00, 0x00 };

    ssize_t sReadLen = 0;
    bool bPackageHeader = false;
    bool bPackageEnd = false;
    do
    {
        sReadLen = read(sock, szBuffer, sizeof(szBuffer) - 1);
        printf("%s", szBuffer);
        if (sReadLen > 0)
        {
            if (!bPackageHeader)
            {
                if (szBuffer[0] == FS[0])
                {
                    sReadLen = read(sock, szBuffer, sizeof(szBuffer) - 1);
                    printf("%s", szBuffer);
                    if(sReadLen == 1)
                    {
                        if(szBuffer[0] == FS_XA[1])
                        {
                            sReadLen = read(sock, szBuffer, sizeof(szBuffer) - 1);
                            printf("%s", szBuffer);
                            if(sReadLen == 1)
                            {
                                if(szBuffer[0] == FS_XA[2])
                                {
                                    bPackageHeader = true;
                                    vPackage.push_back(FS_XA[0]);
                                    vPackage.push_back(FS_XA[1]);
                                    vPackage.push_back(FS_XA[2]);
                                }
                            }
                            else
                            {
                                vPackage.clear();
                                sPackage = sReadLen;
                                break;
                            }
                        }
                        continue;
                    }
                    else
                    {
                        vPackage.clear();
                        sPackage = sReadLen;
                        break;
                    }
                }
            }

            if (bPackageHeader)
            {
                vPackage.push_back(szBuffer[0]);
                if (szBuffer[0] == FS[0])
                {
                    sReadLen = read(sock, szBuffer, sizeof(szBuffer) - 1);
                    printf("%s", szBuffer);
                    if(sReadLen == 1)
                    {
                        vPackage.push_back(szBuffer[0]);
                        if(szBuffer[0] == FS_XZ[1])
                        {
                            sReadLen = read(sock, szBuffer, sizeof(szBuffer) - 1);
                            printf("%s", szBuffer);
                            if(sReadLen == 1)
                            {
                                vPackage.push_back(szBuffer[0]);
                                if(szBuffer[0] == FS_XZ[2])
                                {
                                    bPackageEnd = true;
                                    break;
                                }
                            }
                            else
                            {
                                vPackage.clear();
                                sPackage = sReadLen;
                                break; 
                            }
                        }
                    }
                    else
                    {
                        vPackage.clear();
                        sPackage = sReadLen;
                        break; 
                    }
                }
            }
        }
        else if (sReadLen == 0)
        {
            // pipe: 读端一直在读，写端不写了，并且关闭了写端，读端会如何？s == 0，代表对端关闭
            // s == 0: 代表对方关闭,client 退出
            vPackage.clear();
            sPackage = 0;
            break;
        }
        else
        {
            vPackage.clear();
            sPackage = sReadLen;
            break;
        }
    } while (sReadLen);
    
    if(bPackageHeader && bPackageEnd)
    {
        sPackage = vPackage.size();
        for(auto it = vPackage.begin(); it != vPackage.end(); it++)
        {
            printf("%c", *it);
        }
    }
    return sPackage;
}

static void *HandlerClientSock(void *args)
{
    printf("TCP Server client socket start\n");
    pthread_detach(pthread_self());
    CTCPInfo* pTCPInfo = (CTCPInfo*)args;
    if(pTCPInfo == nullptr)
    {
        return nullptr;
    }
    printf("TCP Server client socket Run\n");

    int sock = pTCPInfo->m_nClientSocket;
    while (true)
    {
        std::list<char> vPackage;
        ssize_t nPackageSize = GetPackage(sock, vPackage);
        if (nPackageSize > 0)
        {
            char* pData = new char[nPackageSize + 1];
            if (pData == nullptr)
            {
                continue;
            }
            std::copy(vPackage.begin(), vPackage.end(), pData);
            pData[nPackageSize] = 0x00;

            printf("Recv Package strat:\n");
            for(int i = 0; i < nPackageSize; i++)
            {
                printf("%c", pData[i]);
            }
            printf("\n");
            printf("Recv Package end\n");

            CTCPClient tcpclient;
            if(tcpclient.Init())
            {
                tcpclient.SendData(pData, nPackageSize);
            }
            //write(sock, inbuffer, strlen(inbuffer));

            delete[] pData;
        }
        else if (nPackageSize == 0)
        {
            // pipe: 读端一直在读，写端不写了，并且关闭了写端，读端会如何？s == 0，代表对端关闭
            // s == 0: 代表对方关闭,client 退出
            printf("client close socket\n");
            break;
        }
        else
        {
            printf("client close error\n");
            break;
        }
    }

    delete pTCPInfo;

    return nullptr;
}

bool CTCPServer::Run()
{
    printf("TCP Server Run\n");
    while(!m_bIsRunning)
    {
        struct sockaddr_in peer;
        socklen_t len = sizeof(peer);

        printf("TCP Server Run wait accept\n");
        int sockfd = accept(m_socketServer, (struct sockaddr*)&peer, &len);
        if(sockfd > 0)
        {
            printf("TCP Server Run new socket success\n");
            CTCPInfo* pTCPInfo = new CTCPInfo(sockfd);
            pthread_t thread;
            pthread_create(&thread, nullptr, HandlerClientSock, pTCPInfo);

            continue;
        }
        else
        {
            break;
        }
    }

    return true;
}